home *** CD-ROM | disk | FTP | other *** search
- /* advdbs.c - adventure database access routines */
- /*
- Copyright (c) 1986, by David Michael Betz
- All rights reserved
- */
-
- #include "advint.h"
- #include "advdbs.h"
- #ifdef MAC
- #include <fnctl.h>
- #define RMODE (O_RDONLY|O_BINARY)
- #else
- #include <setjmp.h>
- #define RMODE 0
- #endif
-
- /* global variables */
- int h_init; /* initialization code */
- int h_update; /* update code */
- int h_before; /* before handler code */
- int h_after; /* after handler code */
- int h_error; /* error handling code */
- int datafd; /* data file descriptor */
-
- /* external variables */
- extern jmp_buf restart;
-
- /* external routines */
- extern char *malloc();
-
- /* table base addresses */
- char *wtable; /* word table */
- char *wtypes; /* word type table */
- int wcount; /* number of words */
- char *otable; /* object table */
- int ocount; /* number of objects */
- char *atable; /* action table */
- int acount; /* number of actions */
- char *vtable; /* variable table */
- int vcount; /* number of variables */
- char *data; /* base of data tables */
- char *base; /* current base address */
- char *dbase; /* base of the data space */
- char *cbase; /* base of the code space */
- int length; /* length of resident data structures */
-
- /* data file header */
- static char hdr[HDR_SIZE];
-
- /* save parameters */
- static long saveoff; /* save data file offset */
- static char *save; /* save area base address */
- static int slen; /* save area length */
-
- /* db_init - read and decode the data file header */
- db_init(name)
- char *name;
- {
- int woff,ooff,aoff,voff,n;
- char fname[50];
-
- /* get the data file name */
- strcpy(fname,name);
- #ifndef MAC
- strcat(fname,".dat");
- #endif
-
- /* open the data file */
- if ((datafd = open(fname,RMODE)) == -1)
- error("can't open data file");
-
- /* read the header */
- if (read(datafd,hdr,HDR_SIZE) != HDR_SIZE)
- error("bad data file");
- complement(hdr,HDR_SIZE);
- base = hdr;
-
- /* check the magic information */
- if (strncmp(&hdr[HDR_MAGIC],"ADVSYS",6) != 0)
- error("not an adventure data file");
-
- /* check the version number */
- if ((n = getword(HDR_VERSION)) < 101 || n > VERSION)
- error("wrong version number");
-
- /* decode the resident data length header field */
- length = getword(HDR_LENGTH);
-
- /* allocate space for the resident data structure */
- if ((data = malloc(length)) == 0)
- error("insufficient memory");
-
- /* compute the offset to the data */
- saveoff = (long)getword(HDR_DATBLK) * 512L;
-
- /* read the resident data structure */
- lseek(datafd,saveoff,0);
- if (read(datafd,data,length) != length)
- error("bad data file");
- complement(data,length);
-
- /* get the table base addresses */
- wtable = data + (woff = getword(HDR_WTABLE));
- wtypes = data + getword(HDR_WTYPES) - 1;
- otable = data + (ooff = getword(HDR_OTABLE));
- atable = data + (aoff = getword(HDR_ATABLE));
- vtable = data + (voff = getword(HDR_VTABLE));
-
- /* get the save data area */
- saveoff += (long)getword(HDR_SAVE);
- save = data + getword(HDR_SAVE);
- slen = getword(HDR_SLEN);
-
- /* get the base of the data and code spaces */
- dbase = data + getword(HDR_DBASE);
- cbase = data + getword(HDR_CBASE);
-
- /* initialize the message routines */
- msg_init(datafd,getword(HDR_MSGBLK));
-
- /* get the code pointers */
- h_init = getword(HDR_INIT);
- h_update = getword(HDR_UPDATE);
- h_before = getword(HDR_BEFORE);
- h_after = getword(HDR_AFTER);
- h_error = getword(HDR_ERROR);
-
- /* get the table lengths */
- base = data;
- wcount = getword(woff);
- ocount = getword(ooff);
- acount = getword(aoff);
- vcount = getword(voff);
-
- /* setup the base of the resident data */
- base = dbase;
-
- /* set the object count */
- setvalue(V_OCOUNT,ocount);
- }
-
- /* db_save - save the current database */
- db_save(name)
- char *name;
- {
- return (advsave(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
- }
-
- /* db_restore - restore a saved database */
- int db_restore(name)
- char *name;
- {
- return (advrestore(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
- }
-
- /* db_restart - restart the current game */
- db_restart()
- {
- lseek(datafd,saveoff,0);
- if (read(datafd,save,slen) != slen)
- return (NIL);
- complement(save,slen);
- setvalue(V_OCOUNT,ocount);
- longjmp(restart,1);
- }
-
- /* complement - complement a block of memory */
- complement(adr,len)
- char *adr; int len;
- {
- for (; len--; adr++)
- *adr = ~(*adr + 30);
- }
-
- /* findword - find a word in the dictionary */
- int findword(word)
- char *word;
- {
- char sword[WRDSIZE+1];
- int wrd,i;
-
- /* shorten the word */
- strncpy(sword,word,WRDSIZE); sword[WRDSIZE] = 0;
-
- /* look up the word */
- for (i = 1; i <= wcount; i++) {
- wrd = getwloc(i);
- if (strcmp(base+wrd+2,sword) == 0)
- return (getword(wrd));
- }
- return (NIL);
- }
-
- /* wtype - return the type of a word */
- int wtype(wrd)
- int wrd;
- {
- return (wtypes[wrd]);
- }
-
- /* match - match an object against a name and list of adjectives */
- int match(obj,noun,adjs)
- int obj,noun,*adjs;
- {
- int *aptr;
-
- if (!hasnoun(obj,noun))
- return (FALSE);
- for (aptr = adjs; *aptr != NIL; aptr++)
- if (!hasadjective(obj,*aptr))
- return (FALSE);
- return (TRUE);
- }
-
- /* checkverb - check to see if this is a valid verb */
- int checkverb(verbs)
- int *verbs;
- {
- int act;
-
- /* look up the action */
- for (act = 1; act <= acount; act++)
- if (hasverb(act,verbs))
- return (act);
- return (NIL);
- }
-
- /* findaction - find an action matching a description */
- findaction(verbs,preposition,flag)
- int *verbs,preposition,flag;
- {
- int act,mask;
-
- /* look up the action */
- for (act = 1; act <= acount; act++) {
- if (preposition && !haspreposition(act,preposition))
- continue;
- if (!hasverb(act,verbs))
- continue;
- mask = ~getabyte(act,A_MASK);
- if ((flag & mask) == (getabyte(act,A_FLAG) & mask))
- return (act);
- }
- return (NIL);
- }
-
- /* getp - get the value of an object property */
- int getp(obj,prop)
- int obj,prop;
- {
- int p;
-
- for (; obj; obj = getofield(obj,O_CLASS))
- if (p = findprop(obj,prop))
- return (getofield(obj,p));
- return (NIL);
- }
-
- /* setp - set the value of an object property */
- int setp(obj,prop,val)
- int obj,prop,val;
- {
- int p;
-
- for (; obj; obj = getofield(obj,O_CLASS))
- if (p = findprop(obj,prop))
- return (putofield(obj,p,val));
- return (NIL);
- }
-
- /* findprop - find a property */
- int findprop(obj,prop)
- int obj,prop;
- {
- int n,i,p;
-
- n = getofield(obj,O_NPROPERTIES);
- for (i = p = 0; i < n; i++, p += 4)
- if ((getofield(obj,O_PROPERTIES+p) & ~P_CLASS) == prop)
- return (O_PROPERTIES+p+2);
- return (NIL);
- }
-
- /* hasnoun - check to see if an object has a specified noun */
- int hasnoun(obj,noun)
- int obj,noun;
- {
- while (obj) {
- if (inlist(getofield(obj,O_NOUNS),noun))
- return (TRUE);
- obj = getofield(obj,O_CLASS);
- }
- return (FALSE);
- }
-
- /* hasadjective - check to see if an object has a specified adjective */
- int hasadjective(obj,adjective)
- int obj,adjective;
- {
- while (obj) {
- if (inlist(getofield(obj,O_ADJECTIVES),adjective))
- return (TRUE);
- obj = getofield(obj,O_CLASS);
- }
- return (FALSE);
- }
-
- /* hasverb - check to see if this action has this verb */
- int hasverb(act,verbs)
- int act,*verbs;
- {
- int link,word,*verb;
-
- /* get the list of verbs */
- link = getafield(act,A_VERBS);
-
- /* look for this verb */
- while (link != NIL) {
- verb = verbs;
- word = getword(link+L_DATA);
- while (*verb != NIL && word != NIL) {
- if (*verb != getword(word+L_DATA))
- break;
- verb++;
- word = getword(word+L_NEXT);
- }
- if (*verb == NIL && word == NIL)
- return (TRUE);
- link = getword(link+L_NEXT);
- }
- return (FALSE);
- }
-
- /* haspreposition - check to see if an action has a specified preposition */
- int haspreposition(act,preposition)
- int act,preposition;
- {
- return (inlist(getafield(act,A_PREPOSITIONS),preposition));
- }
-
- /* inlist - check to see if a word is an element of a list */
- int inlist(link,word)
- int link,word;
- {
- while (link != NIL) {
- if (word == getword(link+L_DATA))
- return (TRUE);
- link = getword(link+L_NEXT);
- }
- return (FALSE);
- }
-
- /* getofield - get a field from an object */
- int getofield(obj,off)
- int obj,off;
- {
- return (getword(getoloc(obj)+off));
- }
-
- /* putofield - put a field into an object */
- int putofield(obj,off,val)
- int obj,off,val;
- {
- return (putword(getoloc(obj)+off,val));
- }
-
- /* getafield - get a field from an action */
- int getafield(act,off)
- int act,off;
- {
- return (getword(getaloc(act)+off));
- }
-
- /* getabyte - get a byte field from an action */
- int getabyte(act,off)
- int act,off;
- {
- return (getbyte(getaloc(act)+off));
- }
-
- /* getoloc - get an object from the object table */
- int getoloc(n)
- int n;
- {
- if (n < 1 || n > ocount)
- nerror("object number out of range: %d",n);
- return (getdword(otable+n+n));
- }
-
- /* getaloc - get an action from the action table */
- int getaloc(n)
- int n;
- {
- if (n < 1 || n > acount)
- nerror("action number out of range: %d",n);
- return (getdword(atable+n+n));
- }
-
- /* getvalue - get the value of a variable from the variable table */
- int getvalue(n)
- int n;
- {
- if (n < 1 || n > vcount)
- nerror("variable number out of range: %d",n);
- return (getdword(vtable+n+n));
- }
-
- /* setvalue - set the value of a variable in the variable table */
- int setvalue(n,v)
- int n,v;
- {
- if (n < 1 || n > vcount)
- nerror("variable number out of range: %d",n);
- return (putdword(vtable+n+n,v));
- }
-
- /* getwloc - get a word from the word table */
- int getwloc(n)
- int n;
- {
- if (n < 1 || n > wcount)
- nerror("word number out of range: %d",n);
- return (getdword(wtable+n+n));
- }
-
- /* getword - get a word from the data array */
- int getword(n)
- int n;
- {
- return (getdword(base+n));
- }
-
- /* putword - put a word into the data array */
- int putword(n,w)
- int n,w;
- {
- return (putdword(base+n,w));
- }
-
- /* getbyte - get a byte from the data array */
- int getbyte(n)
- int n;
- {
- return (*(base+n) & 0xFF);
- }
-
- /* getcbyte - get a code byte */
- int getcbyte(n)
- int n;
- {
- return (*(cbase+n) & 0xFF);
- }
-
- /* getcword - get a code word */
- int getcword(n)
- int n;
- {
- return (getdword(cbase+n));
- }
-
- /* getdword - get a word from the data array */
- int getdword(p)
- char *p;
- {
- return ((*p & 0xFF) | (*(p+1) << 8));
- }
-
- /* putdword - put a word into the data array */
- int putdword(p,w)
- char *p; int w;
- {
- *p = w; *(p+1) = w >> 8;
- return (w);
- }
-
- /* nerror - handle errors with numeric arguments */
- nerror(fmt,n)
- char *fmt; int n;
- {
- char buf[100];
- sprintf(buf,fmt,n);
- error(buf);
- }
-